package org.thingsboard.server.config.factory;

import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import io.netty.handler.codec.mqtt.MqttPublishMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.thingsboard.server.common.transport.adaptor.AdaptorException;
import org.thingsboard.server.config.SpringUtils;
import org.thingsboard.server.dao.jpa.*;
import org.thingsboard.server.dao.jpa.imp.*;
import org.thingsboard.server.transport.mqtt.MqttTopics;
import org.thingsboard.server.transport.mqtt.session.GatewaySessionHandler;
import org.thingsboard.server.utils.msg.MqttReqMsg;

import java.util.ArrayList;
import java.util.Date;
import java.util.TimerTask;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 异步工厂（产生任务用）
 *
 * @author ruoyi
 */
public class AsyncFactory {
    private static final Logger sys_user_logger = LoggerFactory.getLogger("sys-user");
    /**
     * @param json 事件json
     * @return 任务task
     */
    public static TimerTask recordEvent(final MqttReqMsg msg, final JsonObject json, final TApp app,RedisTemplate redisTemplate) {
        return new TimerTask() {
            @Override
            public void run() {
                if(null==app){
                    System.out.println("未查询到该系统!");
                    return;
                }
                final Gson gson = new Gson();
                TDeviceEvent tDeviceEvent = SpringUtils.getBean(DeviceEventRepository.class).findByDeventCode(json.getAsJsonObject().getAsJsonObject("requestBody").get("eventCode").getAsString());
                if (null != tDeviceEvent) {
                    String stringArg = tDeviceEvent.getDeventArg();
                    ArrayList strs = new ArrayList();
                    if (!stringArg.isEmpty()) {
                        JsonArray values = gson.fromJson(stringArg, JsonObject.class).get("configArg").getAsJsonArray().get(0).getAsJsonObject().get("value").getAsJsonArray();
                        strs = gson.fromJson(values, ArrayList.class);
                    }
                    JsonArray jsonArray = json.getAsJsonObject().getAsJsonObject("requestBody").get("eventArg").getAsJsonArray();
                    for (JsonElement element : jsonArray) {
                        if (strs.contains("ram")) {
                            ConcurrentHashMap<String,Object> deviceEventManagement = SpringUtils.getBean("deviceEventManagement");
                            deviceEventManagement.put(app.getAppCode() + json.getAsJsonObject().getAsJsonObject("requestBody").get("deviceCode").getAsString() + ":" + element.getAsJsonObject().get("key").getAsString(), element.getAsJsonObject().get("value").getAsString());
                        }
                        if (strs.contains("redis")) {
                            redisTemplate.opsForValue().set(app.getAppCode() + json.getAsJsonObject().getAsJsonObject("requestBody").get("deviceCode").getAsString() + ":" + element.getAsJsonObject().get("key").getAsString(), element.getAsJsonObject().get("value").getAsString());
                        }
                        if (strs.contains("db")) {
                            String eventType = json.getAsJsonObject().getAsJsonObject("requestBody").get("eventType").getAsString();
                            if (eventType.equals("etype-alarm")) {
                                TAlarm tAlarm = new TAlarm();
                                JsonArray asJsonArray = json.getAsJsonObject().getAsJsonObject("requestBody").get("eventArg").getAsJsonArray();
                                asJsonArray.forEach(o -> {
                                    JsonObject jo = (JsonObject) o;
                                    if (null != jo.get("key") && jo.get("key").getAsString().equals("alarmDes")) {
                                        tAlarm.setAlarmDes(jo.get("value").getAsString());
                                    }
                                    if (null != jo.get("key") && jo.get("key").getAsString().equals("alarmVal")) {
                                        tAlarm.setAlarmVal(jo.get("value").getAsString());
                                    }
                                    if (null != jo.get("key") && jo.get("key").getAsString().equals("alarmLevel")) {
                                        tAlarm.setAlarmLevel(jo.get("value").getAsString());
                                    }
                                });
                                tAlarm.setAlarmId(UUID.randomUUID().toString().replace("-", ""));
                                tAlarm.setAlarmTime(new Date(msg.getRequestHead().getTimestamp()));
                                tAlarm.setDeviceCode(json.getAsJsonObject().getAsJsonObject("requestBody").get("deviceCode").getAsString());
                                SpringUtils.getBean(TAlarmRepository.class).save(tAlarm);
                            } else {
                                TEvent tEvent = new TEvent();
                                tEvent.setEventId(UUID.randomUUID().toString().replace("-", ""));
                                tEvent.setDeviceCode(json.getAsJsonObject().getAsJsonObject("requestBody").get("deviceCode").getAsString());
                                tEvent.setEventTime(new Date(msg.getRequestHead().getTimestamp()));
                                tEvent.setEventVal(json.getAsJsonObject().getAsJsonObject("requestBody").get("eventArg").getAsJsonArray().toString());
                                SpringUtils.getBean(TEventRepository.class).save(tEvent);
                            }
                        }
                    }

                }
            }
        };
    }

    /**
     * @param jsonObject 事件json
     * @return 任务task
     */
//    public static TimerTask recordAttr(final MqttReqMsg msg, final JsonObject jsonObject,RedisTemplate redisTemplate) {
//        return new TimerTask() {
//            @Override
//            public void run() {
//                final Gson gson = new Gson();
//                String deviceCode = jsonObject.getAsJsonObject("requestBody").get("deviceCode").getAsString();
//                JsonArray jsonArray = jsonObject.getAsJsonObject("requestBody").get("propertyList").getAsJsonArray();
//                for (JsonElement element : jsonArray) {
//                    TDeviceProperty tDeviceProperty = SpringUtils.getBean(DevicePropertyRepository.class).findByDpropertyCode(element.getAsJsonObject().get("key").getAsString());
//                    ArrayList strs = new ArrayList();
//                    String stringArg = tDeviceProperty.getDpropertyArg();
//                    if (!stringArg.isEmpty()) {
//                        JsonArray values = gson.fromJson(stringArg, JsonObject.class).get("configArg").getAsJsonArray().get(0).getAsJsonObject().get("value").getAsJsonArray();
//                        strs = gson.fromJson(values, ArrayList.class);
//                    }
//                    if (strs.contains("ram")) {
//                        ConcurrentHashMap<String,String> deviceAttrManagement = SpringUtils.getBean("deviceAttrManagement");
//                        deviceAttrManagement.put(deviceCode + element.getAsJsonObject().get("key").getAsString(), element.getAsJsonObject().toString());
//                    }
//                    if (strs.contains("redis")) {
//                        redisTemplate.opsForValue().set(deviceCode + element.getAsJsonObject().get("key").getAsString(), element.getAsJsonObject().toString());
//                    }
//                    if (strs.contains("db")) {
//                        TData tData = new TData();
//                        tData.setDataId(UUID.randomUUID().toString().replace("-", ""));
//                        tData.setDataTime(new Date(msg.getRequestHead().getTimestamp()));
//                        tData.setDeviceCode(deviceCode);
//                        tData.setDataVal(element.getAsJsonObject().get("key").getAsString());
//                        tData.setDpropertyCode(element.getAsJsonObject().get("value").getAsString());
//                        SpringUtils.getBean(DataRepository.class).save(tData);
//                    }
//                }
//            }
//        };
//    }

}

